package com.yu.waterstation.app.moudles.task.service;

import com.yu.waterstation.app.moudles.address.mapper.AddressMapper;
import com.yu.waterstation.common.entity.app.*;
import com.yu.waterstation.app.moudles.student.mapper.StudentMapper;
import com.yu.waterstation.common.entity.app.dto.StudentDTO;
import com.yu.waterstation.app.moudles.student.service.StudentServiceImpl;
import com.yu.waterstation.app.moudles.task.mapper.TaskMapper;
import com.yu.waterstation.common.entity.app.dto.TaskDTO;
import com.yu.waterstation.common.entity.app.form.FinishTaskForm;
import com.yu.waterstation.app.moudles.tasklog.mapper.TaskLogMapper;
import com.yu.waterstation.app.moudles.worker.mapper.WorkerMapper;
import com.yu.waterstation.common.common.exception.ServiceException;
import com.yu.waterstation.common.common.util.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
public class TaskServiceImpl implements TaskService {
    @Resource
    private TaskMapper taskMapper;
    @Resource
    private StudentServiceImpl studentService;
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private WorkerMapper workerMapper;
    @Resource
    private AddressMapper addressMapper;
    @Resource
    private TaskLogMapper taskLogMapper;

    @Override
    public List<TaskDTO> getTaskOfDorm(String dorm) {
        return taskMapper.getTaskOfDorm(dorm);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer addTask(Integer studentId) throws ServiceException {
        StudentDTO studentDTO = studentService.getStudentInfo(studentId);

        if (studentDTO.getAddressId() == null || studentDTO.getAddress() == null)
            throw ServiceException.CONST_address_not_exist;
        if (studentDTO.getAddress().getTicketNum() <= 0)
            throw ServiceException.CONST_ticket_num_not_enough;
        Task task = taskMapper.selectById(studentDTO.getAddressId());
        if (task != null)
            throw ServiceException.CONST_this_address_has_already_posted_a_task;

        task = new Task();
        task.setAddressId(studentDTO.getAddressId());
        task.setPublisher(studentDTO.getName());
        task.setTimestamp(new Date());
        return taskMapper.insert(task);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer cancelTask(Integer studentId) throws ServiceException {
        Student student = studentMapper.selectById(studentId);
        if (student.getAddressId() == null)
            throw ServiceException.CONST_has_not_set_address;
        return taskMapper.deleteById(student.getAddressId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<TaskLog> finishTask(Integer workerId, FinishTaskForm vo) {
        Worker worker = workerMapper.selectById(workerId);
        Task task = taskMapper.selectById(vo.getAddressId());
        if (task == null)
            return Result.fail("任务不存在");

        Address address = addressMapper.selectById(task.getAddressId());
        if (address == null)
            return Result.fail("地址不存在");

        // 检验数据的合法性
        if (vo.getReceiveEmptyBucketNum() > address.getBucketNum())
            return Result.fail("收到的空桶数不合法");

        taskMapper.deleteById(vo.getAddressId());

        // 更新寝室
        int bucketNum = address.getBucketNum() - vo.getReceiveEmptyBucketNum() + vo.getBucketNum();
        int ticketNum = address.getTicketNum() - vo.getBucketNum();
        address.setBucketNum(bucketNum);
        address.setTicketNum(ticketNum);
        address.setLastTime(new Date());
        addressMapper.updateById(address);

        // 添加日志
        TaskLog taskLog = new TaskLog();
        taskLog.setAddressId(task.getAddressId());
        taskLog.setDorm(address.getDorm());
        taskLog.setRoom(address.getRoom());
        taskLog.setTimestamp(address.getLastTime());
        taskLog.setWaterPrice(address.getWaterPrice());
        taskLog.setBucketNum(vo.getBucketNum());
        taskLog.setReceiveEmptyBucketNum(vo.getReceiveEmptyBucketNum());
        taskLog.setPublisher(task.getPublisher());
        taskLog.setWorkerId(workerId);
        taskLog.setWorkerName(worker.getName());
        taskLogMapper.insert(taskLog);
        return Result.ok(taskLog);

    }

}
